package ch.exm.storm.loader.hibernate;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;

import ch.exm.storm.log.Logger;

class HibernateConfiguration {
	
	private Configuration configuration;

	private SessionFactory sessionFactory;
	
	private Map<Class<?>, PersistentClass> classMapping = new HashMap<Class<?>, PersistentClass>();

	HibernateConfiguration() { this(null); }
	
	HibernateConfiguration(Configuration configuration) {
		this.configuration = configuration;
		parseConfiguration();
		sessionFactory = this.configuration.buildSessionFactory();
	}

	SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
	PersistentClass getPersistentClass(Class<?> clazz) {
		return classMapping.get(clazz);
	}
	
	Collection<Class<?>> getAllMappedClasses() {
		return classMapping.keySet();
	}
	
	// ////////////////////////////////////////////////////////////////////////
	// /// Hibernate Configuration Parser
	// ////////////////////////////////////////////////////////////////////////
	
	private void parseConfiguration() {
		Iterator<?> mappingIterator = getConfiguration().getClassMappings();
		while (mappingIterator.hasNext()) {
			addMappedClass((PersistentClass)mappingIterator.next());
		}
	}
	
	private void addMappedClass(PersistentClass mappedClass) {
		Logger.debug(this, "Parsing persistent class: " + mappedClass);
		classMapping.put(mappedClass.getMappedClass(), mappedClass);
		Class<?> proxyClass = mappedClass.getProxyInterface();
		if (proxyClass != null) classMapping.put(proxyClass, mappedClass);
	}
	
	private Configuration getConfiguration() {
		if (configuration == null) {
			configuration = new Configuration().configure();
//			configuration.addResource("hibernate.cfg.xml");
			configuration.buildMappings();
		}
		return configuration;
	}
	
	private Property getMappedProperty(PersistentClass mappedClass, String propertyName) {
		try {
			return mappedClass.getProperty(propertyName);
		} catch (MappingException me) { }
		return null;
	}
}
